import { _decorator, Component, JsonAsset, resources, sys } from 'cc';
const { ccclass, property } = _decorator;

const userDataKey = 'userData';

interface MapItemData {
    name: string,
    type: string,
    color: string,
    resources: string[],
    monsters: string[],
    buildings: [],
    events: [],
    // probability: number,
    rules: any,
    position: { x: number, y: number }
}

interface UserData {
    name: string
    race: string
    startPoint: string
    curMap: string
    position:{x:number,y:number}
}

interface Monsters{
    id:string
    probability:number
}

interface Resource{
    id:string
    probability:number
}
@ccclass('MG3')
export class MG3 extends Component {

    @property
    private mapData: MapItemData[] = [];

    //世界尺寸
    private WorldSize:number=3;
    // 地图尺寸
    private mapWidth: number = 10;
    private mapHeight: number = 10;
    //玩家开始游戏时进入地图中的位置
    private posx=0;
    private posy=0;

    mapColor: { name: string, color: string }[] = []

    private tileTypes: string[] = [];
    private resourceTypes: {tile: string,res:Resource[]}[] = [];
    private monsterTypes: {tile: string,mons:Monsters[]}[] = [];
    // 生成概率
    private tileProbabilities: number[] = [];

    /**@param worldRegions 区域地图组 */
    private worldRegions:string[]=["worldRegion1","worldRegion2","worldRegion3"];
    // 生成规则
    private tileRules: { [key: string]: { adjacent: string[], position: { x: number, y: number } } } = {
        '山脉': { adjacent: ['山脉'], position: { x: 0, y: 0 } },
        '森林': { adjacent: ['森林'], position: { x: 0, y: 0 } },
        '河流': { adjacent: ['河流'], position: { x: 0, y: 0 } },
        '沙漠': { adjacent: ['沙漠'], position: { x: 0, y: 0 } }
    };

    loadMapData(path: string, callback: () => void) {
        // 从本地存储中加载地图生成数据
        resources.load(path, JsonAsset, (err, jsonAsset) => {
            if (err) {
                console.error(err);
                return;
            }
            const mapData = jsonAsset.json;
            this.mapWidth = mapData.mapSize;
            this.mapHeight = mapData.mapSize;

            mapData.tiles.forEach(tile => {
                this.mapColor.push({ name: tile.name, color: tile.color });
                this.tileTypes.push(tile.name);
                this.tileProbabilities.push(tile.probability);
                this.monsterTypes.push({tile:tile.name,mons:tile.monsters});
                this.resourceTypes.push({tile:tile.name,res:tile.resources});
            });
            this.posx=Math.floor(Math.random()*mapData.mapSize);
            this.posy=Math.floor(Math.random()*mapData.mapSize);

            // 数据加载完成后调用回调函数
            callback();
        });
    }

    start() {

        
    }

    public loadDataGener(path:string){
        this.loadMapData('jsons/ditu/'+path, () => {
            this.generateMap();
        });
    }
    loadUserData() {

        const jsonStr = sys.localStorage.getItem(userDataKey);
        const userData = JSON.parse(jsonStr) as UserData;
        return userData;
    }
    update(deltaTime: number) {

    }

    public generateMap(): any[] {
        const map: MapItemData[][] = [];


        for (let y = 0; y < this.mapHeight; y++) {
            const row: MapItemData[] = [];

            for (let x = 0; x < this.mapWidth; x++) {
                const tile: MapItemData = this.generateTile(x, y);
                this.mapData.push(tile);
                row.push(tile);
            }

            map.push(row);
        }
        this.saveMapData();
        this.saveUserData();
        return map;
    }

    saveUserData() {
            const userData = {
                name: this.loadUserData().name,
                race: this.loadUserData().race,
                startPoint: this.loadUserData().startPoint,
                curMap: this.loadUserData().curMap,
                position:{x:this.posx,y:this.posy}
            };
            const jsonStr = JSON.stringify(userData);
            sys.localStorage.setItem(userDataKey, jsonStr);
        }
    // 生成地块
    generateTile(x: number, y: number): any {
        const tileType = this.getRandomTileType();

        const tile: MapItemData = {
            name: tileType,
            type: 'land',
            color: this.getColorByName(tileType),
            resources: this.getRandomResources(tileType),
            monsters: this.getRandomMonsters(tileType),
            buildings: [],
            events: [],
            // probability: this.tileProbabilities[this.tileTypes.indexOf(tileType)],
            rules: this.tileRules[tileType],
            position:{x:x,y:y}
        };

        return tile;
    }

    getColorByName(name: string) {
        return this.mapColor.find(i => (i.name === name)).color;
    }

    // 获取随机地形类型
    getRandomTileType(): string {
        const random = Math.random();
        let cumulativeProbability = 0;

        for (let i = 0; i < this.tileTypes.length; i++) {
            cumulativeProbability += this.tileProbabilities[i];

            if (random < cumulativeProbability) {
                return this.tileTypes[i];
            }
        }
        return this.tileTypes[this.tileTypes.length - 1];
    }

    saveMapData() {
        const mapData = {
            name: this.loadUserData().curMap,
            tiles: this.mapData
        };
        const jsonString = JSON.stringify(mapData);
        sys.localStorage.setItem(this.loadUserData().curMap+'MinimapData', jsonString);
    }

    // 获取随机资源类型
    getRandomResources(tile:string): string[] {
        //找到对应地形下的资源组
        const tileResources=this.resourceTypes.find(i=>i.tile===tile);
        const resources: string[] = [];

        for (let i = 0; i < tileResources.res.length; i++) {
            if (Math.random() < tileResources.res[i].probability) {
                resources.push(tileResources.res[i].id);
            }
        }

        return resources;
    }

    // 获取随机怪物类型
    getRandomMonsters(tile:string): string[] {
        const tileMonsters=this.monsterTypes.find(i=>i.tile===tile);
        const monsters: string[] = [];

        for (let i = 0; i < tileMonsters.mons.length; i++) {
            if (Math.random() < tileMonsters.mons[i].probability) {
                monsters.push(tileMonsters.mons[i].id);
            }
        }

        return monsters;
    }
}